package com.project.school_flate.serviceimpl.shop;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.project.school_flate.dto.shop.ShopCommodityEvaluateDto;
import com.project.school_flate.entity.delivery.DeliveryInfo;
import com.project.school_flate.entity.order.OrderDelivery;
import com.project.school_flate.entity.order.OrderTakeaway;
import com.project.school_flate.entity.order.OrderTakeawayCommodity;
import com.project.school_flate.entity.order.table.OrderDeliveryTableDef;
import com.project.school_flate.entity.order.table.OrderTakeawayCommodityTableDef;
import com.project.school_flate.entity.order.table.OrderTakeawayTableDef;
import com.project.school_flate.entity.shop.ShopCommodity;
import com.project.school_flate.entity.shop.ShopCommodityEvaluate;
import com.project.school_flate.entity.shop.ShopInfo;
import com.project.school_flate.entity.shop.table.ShopCommodityTableDef;
import com.project.school_flate.entity.table.shop.ShopCommodityEvaluateTable;
import com.project.school_flate.mapper.delivery.DeliveryEvaluateMapper;
import com.project.school_flate.mapper.delivery.DeliveryInfoMapper;
import com.project.school_flate.mapper.order.OrderDeliveryMapper;
import com.project.school_flate.mapper.order.OrderTakeawayCommodityMapper;
import com.project.school_flate.mapper.order.OrderTakeawayMapper;
import com.project.school_flate.mapper.shop.ShopCommodityEvaluateMapper;
import com.project.school_flate.mapper.shop.ShopCommodityMapper;
import com.project.school_flate.mapper.shop.ShopInfoMapper;
import com.project.school_flate.service.shop.ShopCommodityEvaluateService;
import com.project.school_flate.util.PoToDTO;
import com.project.school_flate.util.Result.Result;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 *  服务层实现。
 *
 * @author 马维健
 * @since 2024/1/2
 */
@Service
public class ShopCommodityEvaluateServiceImpl extends ServiceImpl<ShopCommodityEvaluateMapper, ShopCommodityEvaluate> implements ShopCommodityEvaluateService {

    @Autowired
    private ShopCommodityEvaluateMapper oShopCommodityEvaluateMapper;

    @Autowired
    private ShopCommodityMapper oShopCommodityMapper;

    @Autowired
    private ShopInfoMapper oShopInfoMapper;

    @Autowired
    private OrderTakeawayMapper oOrderTakeawayMapper;

    @Autowired
    private OrderTakeawayCommodityMapper oOrderTakeawayCommodityMapper;

    @Autowired
    private DeliveryInfoMapper oDeliveryInfoMapper;

    @Autowired
    private DeliveryEvaluateMapper oDeliveryEvaluateMapper;

    @Autowired
    private OrderDeliveryMapper oOrderDeliveryMapper;

    /**
     * 获取商品评价
     * @param oShopCommodityEvaluateDto
     * @return
     * @throws Exception
     */
    @Override
    public Result getShopCommodityEvaluate(ShopCommodityEvaluateDto oShopCommodityEvaluateDto) throws Exception {
        List<ShopCommodityEvaluate> oShopCommodityEvaluateList = new ArrayList<>();
        long total = 0;
        QueryWrapper queryWrapper = new QueryWrapper();
        //判断是否传入商品ID
        if(StringUtils.isNotBlank(oShopCommodityEvaluateDto.getCommodityId())){
            queryWrapper.where(ShopCommodityEvaluateTable.SHOP_COMMODITY_EVALUATE.COMMODITY_ID.eq(oShopCommodityEvaluateDto.getCommodityId()));
        }
        queryWrapper.orderBy("create_time desc");
        //是否分页
        if(oShopCommodityEvaluateDto.getPage() != null && oShopCommodityEvaluateDto.getLimit() != null){
            Page<ShopCommodityEvaluate> ShopCommodityEvaluatePage = oShopCommodityEvaluateMapper.paginateWithRelations(oShopCommodityEvaluateDto.getPage(),oShopCommodityEvaluateDto.getLimit(),queryWrapper);
            oShopCommodityEvaluateList = ShopCommodityEvaluatePage.getRecords();
            total = ShopCommodityEvaluatePage.getTotalRow();
        }else{
            oShopCommodityEvaluateList = oShopCommodityEvaluateMapper.selectListWithRelationsByQuery(queryWrapper);
            total = oShopCommodityEvaluateList.size();
        }
        //PoToDto
        List<ShopCommodityEvaluateDto> oShopCommodityEvaluateDtoList = (List<ShopCommodityEvaluateDto>) PoToDTO.poToDtoList(oShopCommodityEvaluateList,new ShopCommodityEvaluateDto());
        return Result.ok(oShopCommodityEvaluateDtoList,total);
    }

    /**
     * 添加商品评价
     * @param oShopCommodityEvaluateDto
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public Result addShopCommodityEvaluate(ShopCommodityEvaluateDto oShopCommodityEvaluateDto) throws Exception {
        //重新获取订单信息
        OrderTakeaway oOrderTakeaway = oOrderTakeawayMapper.selectOneById(oShopCommodityEvaluateDto.getOrderTakeawayId());
        if(oOrderTakeaway.getIsEvaluate() == 1){
            return Result.error("此订单已评价");
        }
        //计算评分
        int sum = 0;
        double score = 0.0;
        if(oShopCommodityEvaluateDto.getServiceRating() != null){
            sum++;
            score += oShopCommodityEvaluateDto.getServiceRating();
        }
        if(oShopCommodityEvaluateDto.getQualityRating() != null){
            sum++;
            score += oShopCommodityEvaluateDto.getQualityRating();
        }
        if(oShopCommodityEvaluateDto.getSpeedRating() != null){
            sum++;
            score += oShopCommodityEvaluateDto.getSpeedRating();
        }
        Double allRating = Double.parseDouble(String.format("%.2f",score/sum));
        //获取所有订单商品订单
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.where(OrderTakeawayCommodityTableDef.ORDER_TAKEAWAY_COMMODITY.ORDER_TAKEAWAY_ID.eq(oOrderTakeaway.getId()));
        List<OrderTakeawayCommodity> oOrderTakeawayCommodityList = oOrderTakeawayCommodityMapper.selectListByQuery(queryWrapper);
        if(CollectionUtils.isNotEmpty(oOrderTakeawayCommodityList)){
            //创建评价集合
            List<ShopCommodityEvaluate> oShopCommodityEvaluateList = new ArrayList<>();
            //创建商品ID集合
            List<String> oShopCommodityIdList = new ArrayList<>();
            for(OrderTakeawayCommodity oOrderTakeawayCommodity : oOrderTakeawayCommodityList){
                oShopCommodityIdList.add(oOrderTakeawayCommodity.getCommodityId());
                ShopCommodityEvaluate oShopCommodityEvaluate = new ShopCommodityEvaluate();
                oShopCommodityEvaluate.setCommodityId(oOrderTakeawayCommodity.getCommodityId());
                oShopCommodityEvaluate.setServiceRating(oShopCommodityEvaluateDto.getServiceRating());
                oShopCommodityEvaluate.setQualityRating(oShopCommodityEvaluateDto.getQualityRating());
                oShopCommodityEvaluate.setSpeedRating(oShopCommodityEvaluateDto.getSpeedRating());
                oShopCommodityEvaluate.setUserId(oOrderTakeaway.getUserId());
                oShopCommodityEvaluate.setContent(oShopCommodityEvaluateDto.getContent());
                oShopCommodityEvaluate.setIsAnonymous(oShopCommodityEvaluateDto.getIsAnonymous());
                oShopCommodityEvaluate.setAllRating(allRating);
                oShopCommodityEvaluate.setShopId(oOrderTakeaway.getShopId());
                if(StringUtils.isNotBlank(oShopCommodityEvaluateDto.getEvaluateTemplate())){
                    oShopCommodityEvaluate.setEvaluateTemplate(oShopCommodityEvaluateDto.getEvaluateTemplate());
                }
                oShopCommodityEvaluateList.add(oShopCommodityEvaluate);
            }
            if(oShopCommodityEvaluateMapper.insertBatch(oShopCommodityEvaluateList) == 0){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Result.error("客户商品评价失败");
            }
            //获取商品信息
            queryWrapper = new QueryWrapper();
            queryWrapper.where(ShopCommodityTableDef.SHOP_COMMODITY.ID.in(oShopCommodityIdList));
            List<ShopCommodity> oShopCommodityList = oShopCommodityMapper.selectListByQuery(queryWrapper);
            //修改商品评价次数
            for(ShopCommodity oShopCommodity : oShopCommodityList){
                if(oShopCommodity.getScore().compareTo(allRating) < 0 && StringUtils.isNotBlank(oShopCommodityEvaluateDto.getEvaluateTemplate())){
                    oShopCommodity.setEvaluateTemplate(oShopCommodityEvaluateDto.getEvaluateTemplate());
                }
                oShopCommodity.setScore((oShopCommodity.getScore() * oShopCommodity.getEvaluateNum() + score) / (oShopCommodity.getEvaluateNum() + sum));
                oShopCommodity.setEvaluateNum(oShopCommodity.getEvaluateNum() + 1);
                if(oShopCommodityMapper.update(oShopCommodity) == 0){
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return Result.error("客户商品评价失败");
                }
            }
            //修改店铺评价次数
            ShopInfo oShopInfo = oShopInfoMapper.selectOneById(oOrderTakeaway.getShopId());
            if(oShopInfo.getScore().compareTo(allRating) < 0 && StringUtils.isNotBlank(oShopCommodityEvaluateDto.getEvaluateTemplate())){
                oShopInfo.setEvaluateTemplate(oShopCommodityEvaluateDto.getEvaluateTemplate());
            }
            oShopInfo.setScore((oShopInfo.getScore() * oShopInfo.getEvaluateNum() + score) / (oShopInfo.getEvaluateNum() + sum));
            oShopInfo.setEvaluateNum(oShopInfo.getEvaluateNum() + 1);
            if(oShopInfoMapper.update(oShopInfo) == 0){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Result.error("客户商品评价失败");
            }
        }
        //获取最后送达的配送员
        queryWrapper = new QueryWrapper();
        queryWrapper.where(OrderDeliveryTableDef.ORDER_DELIVERY.ORDER_TAKEAWAY_ID.eq(oOrderTakeaway.getId()));
        queryWrapper.orderBy("reach_time desc");
        queryWrapper.limit(1);
        OrderDelivery oOrderDelivery = oOrderDeliveryMapper.selectOneByQuery(queryWrapper);
        //添加配送员评分
        DeliveryInfo oDeliveryInfo = oDeliveryInfoMapper.selectOneById(oOrderDelivery.getDeliveryId());
        oDeliveryInfo.setScore((oDeliveryInfo.getScore() * oDeliveryInfo.getEvaluateNum() + oShopCommodityEvaluateDto.getDeliveryAllRating()) / (oDeliveryInfo.getEvaluateNum() + 1));
        oDeliveryInfo.setEvaluateNum(oDeliveryInfo.getEvaluateNum() + 1);
        if(oDeliveryInfoMapper.update(oDeliveryInfo) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("客户商品评价失败");
        }
        //修改订单是否评价
        UpdateChain.of(OrderTakeaway.class)
                .set(OrderTakeaway::getIsEvaluate, 1)
                .where(OrderTakeaway::getId).eq(oOrderTakeaway.getId())
                .update();
        return Result.ok("添加商品评价成功");
    }

    /**
     * 修改商品评价
     * @param oShopCommodityEvaluateDto
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public Result updateShopCommodityEvaluate(ShopCommodityEvaluateDto oShopCommodityEvaluateDto) throws Exception {
        ShopCommodityEvaluate oShopCommodityEvaluate = new ShopCommodityEvaluate();
        PoToDTO.poToDto(oShopCommodityEvaluateDto,oShopCommodityEvaluate);
        if(oShopCommodityEvaluateMapper.update(oShopCommodityEvaluate) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("修改商品评价失败");
        }
        return Result.ok("修改商品评价成功");
    }

    /**
     * 删除商品评价
     * @param oShopCommodityEvaluateDto
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public Result deleteShopCommodityEvaluate(ShopCommodityEvaluateDto oShopCommodityEvaluateDto) throws Exception {
        ShopCommodityEvaluate oShopCommodityEvaluate = new ShopCommodityEvaluate();
        PoToDTO.poToDto(oShopCommodityEvaluateDto,oShopCommodityEvaluate);
        if(oShopCommodityEvaluateMapper.deleteById(oShopCommodityEvaluate.getId()) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("删除商品评价失败");
        }
        //修改商品信息
        ShopCommodity oShopCommodity = oShopCommodityMapper.selectOneById(oShopCommodityEvaluate.getCommodityId());
        oShopCommodity.setScore((oShopCommodity.getScore() * oShopCommodity.getEvaluateNum() - oShopCommodityEvaluate.getAllRating()) / (oShopCommodity.getEvaluateNum() - 1));
        oShopCommodity.setEvaluateNum(oShopCommodity.getEvaluateNum() - 1);
        if(oShopCommodityMapper.update(oShopCommodity) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("删除商品评价失败");
        }
        //修改店铺评价次数
        ShopInfo oShopInfo = oShopInfoMapper.selectOneById(oShopCommodityEvaluate.getShopId());
        oShopInfo.setScore((oShopInfo.getScore() * oShopInfo.getEvaluateNum() - oShopCommodityEvaluate.getAllRating()) / (oShopInfo.getEvaluateNum() - 1));
        oShopInfo.setEvaluateNum(oShopInfo.getEvaluateNum() - 1);
        if(oShopInfoMapper.update(oShopInfo) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("删除商品评价失败");
        }
        return Result.ok("删除商品评价成功");
    }

    /**
     * 获取商品评价（客户）
     * @param oShopCommodityEvaluateDto
     * @return
     * @throws Exception
     */
    @Override
    public Result getShopCommodityEvaluateUser(ShopCommodityEvaluateDto oShopCommodityEvaluateDto) throws Exception {
        List<ShopCommodityEvaluate> oShopCommodityEvaluateList = new ArrayList<>();
        long total = 0;
        QueryWrapper queryWrapper = new QueryWrapper();
        //判断是否传入商品ID
        if(StringUtils.isNotBlank(oShopCommodityEvaluateDto.getCommodityId())){
            queryWrapper.where(ShopCommodityEvaluateTable.SHOP_COMMODITY_EVALUATE.COMMODITY_ID.eq(oShopCommodityEvaluateDto.getCommodityId()));
        }
        //判断是否传入店铺ID
        if(StringUtils.isNotBlank(oShopCommodityEvaluateDto.getShopId())){
            queryWrapper.where(ShopCommodityEvaluateTable.SHOP_COMMODITY_EVALUATE.SHOP_ID.eq(oShopCommodityEvaluateDto.getShopId()));
        }
        queryWrapper.orderBy("all_rating desc,create_time desc");
        //是否分页
        if(oShopCommodityEvaluateDto.getPage() != null && oShopCommodityEvaluateDto.getLimit() != null){
            Page<ShopCommodityEvaluate> ShopCommodityEvaluatePage = oShopCommodityEvaluateMapper.paginateWithRelations(oShopCommodityEvaluateDto.getPage(),oShopCommodityEvaluateDto.getLimit(),queryWrapper);
            oShopCommodityEvaluateList = ShopCommodityEvaluatePage.getRecords();
            total = ShopCommodityEvaluatePage.getTotalRow();
        }else{
            oShopCommodityEvaluateList = oShopCommodityEvaluateMapper.selectListWithRelationsByQuery(queryWrapper);
            total = oShopCommodityEvaluateList.size();
        }
        //PoToDto
        List<ShopCommodityEvaluateDto> oShopCommodityEvaluateDtoList = (List<ShopCommodityEvaluateDto>) PoToDTO.poToDtoList(oShopCommodityEvaluateList,new ShopCommodityEvaluateDto());
        return Result.ok(oShopCommodityEvaluateDtoList,total);
    }

    /**
     * 用户自动商品评价
     * @param oOrderTakeawayId
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public void automaticShopCommodityEvaluate(String oOrderTakeawayId) throws Exception {
        if(StringUtils.isBlank(oOrderTakeawayId)){
            throw new Exception("客户商品评价失败");
        }
        //重新获取订单
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.where(OrderTakeawayTableDef.ORDER_TAKEAWAY.ID.eq(oOrderTakeawayId));
        queryWrapper.where(OrderTakeawayTableDef.ORDER_TAKEAWAY.PAY_STATE.eq(2));
        queryWrapper.where(OrderTakeawayTableDef.ORDER_TAKEAWAY.SHOP_STATE.eq(2));
        queryWrapper.where(OrderTakeawayTableDef.ORDER_TAKEAWAY.DELIVERY_STATE.eq(3));
        queryWrapper.where(OrderTakeawayTableDef.ORDER_TAKEAWAY.IS_EVALUATE.eq(0));
        OrderTakeaway oOrderTakeaway = oOrderTakeawayMapper.selectOneByQuery(queryWrapper);
        if(oOrderTakeaway != null){
            //获取订单商品
            queryWrapper = new QueryWrapper();
            queryWrapper.where(OrderTakeawayCommodityTableDef.ORDER_TAKEAWAY_COMMODITY.ORDER_TAKEAWAY_ID.eq(oOrderTakeaway.getId()));
            List<OrderTakeawayCommodity> oOrderTakeawayCommodityList = oOrderTakeawayCommodityMapper.selectListByQuery(queryWrapper);
            if(CollectionUtils.isNotEmpty(oOrderTakeawayCommodityList)){
                //创建评价集合
                List<ShopCommodityEvaluate> oShopCommodityEvaluateList = new ArrayList<>();
                //创建商品ID集合
                List<String> oShopCommodityIdList = new ArrayList<>();
                for(OrderTakeawayCommodity oOrderTakeawayCommodity : oOrderTakeawayCommodityList){
                    oShopCommodityIdList.add(oOrderTakeawayCommodity.getCommodityId());
                    ShopCommodityEvaluate oShopCommodityEvaluate = new ShopCommodityEvaluate();
                    oShopCommodityEvaluate.setCommodityId(oOrderTakeawayCommodity.getCommodityId());
                    oShopCommodityEvaluate.setServiceRating(5.0);
                    oShopCommodityEvaluate.setQualityRating(5.0);
                    oShopCommodityEvaluate.setSpeedRating(5.0);
                    oShopCommodityEvaluate.setUserId(oOrderTakeaway.getUserId());
                    oShopCommodityEvaluate.setContent("此用户没有填写文本");
                    oShopCommodityEvaluate.setIsAnonymous(1);
                    oShopCommodityEvaluate.setAllRating(5.0);
                    oShopCommodityEvaluate.setShopId(oOrderTakeaway.getShopId());
                    oShopCommodityEvaluateList.add(oShopCommodityEvaluate);
                }
                if(oShopCommodityEvaluateMapper.insertBatch(oShopCommodityEvaluateList) == 0){
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    throw new Exception("客户商品评价失败");
                }
                //获取商品信息
                queryWrapper = new QueryWrapper();
                queryWrapper.where(ShopCommodityTableDef.SHOP_COMMODITY.ID.in(oShopCommodityIdList));
                List<ShopCommodity> oShopCommodityList = oShopCommodityMapper.selectListByQuery(queryWrapper);
                //修改商品评价次数
                for(ShopCommodity oShopCommodity : oShopCommodityList){
                    oShopCommodity.setScore((oShopCommodity.getScore() * oShopCommodity.getEvaluateNum() + 5.0) / (oShopCommodity.getEvaluateNum() + 1));
                    oShopCommodity.setEvaluateNum(oShopCommodity.getEvaluateNum() + 1);
                    if(oShopCommodityMapper.update(oShopCommodity) == 0){
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        throw new Exception("客户商品评价失败");
                    }
                }
                //修改店铺评价次数
                ShopInfo oShopInfo = oShopInfoMapper.selectOneById(oOrderTakeaway.getShopId());
                oShopInfo.setScore((oShopInfo.getScore() * oShopInfo.getEvaluateNum() + 5.0) / (oShopInfo.getEvaluateNum() + 1));
                oShopInfo.setEvaluateNum(oShopInfo.getEvaluateNum() + 1);
                if(oShopInfoMapper.update(oShopInfo) == 0){
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    throw new Exception("客户商品评价失败");
                }
            }
            //获取最后送达的配送员
            queryWrapper = new QueryWrapper();
            queryWrapper.where(OrderDeliveryTableDef.ORDER_DELIVERY.ORDER_TAKEAWAY_ID.eq(oOrderTakeaway.getId()));
            queryWrapper.orderBy("reach_time desc");
            queryWrapper.limit(1);
            OrderDelivery oOrderDelivery = oOrderDeliveryMapper.selectOneByQuery(queryWrapper);
            //添加配送员评分
            DeliveryInfo oDeliveryInfo = oDeliveryInfoMapper.selectOneById(oOrderDelivery.getDeliveryId());
            oDeliveryInfo.setScore((oDeliveryInfo.getScore() * oDeliveryInfo.getEvaluateNum() + 5.0) / (oDeliveryInfo.getEvaluateNum() + 1));
            oDeliveryInfo.setEvaluateNum(oDeliveryInfo.getEvaluateNum() + 1);
            if(oDeliveryInfoMapper.update(oDeliveryInfo) == 0){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw new Exception("客户商品评价失败");
            }
            //修改订单是否评价
            UpdateChain.of(OrderTakeaway.class)
                    .set(OrderTakeaway::getIsEvaluate, 1)
                    .where(OrderTakeaway::getId).eq(oOrderTakeaway.getId())
                    .update();
        }
    }

}
